﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Monitor.Core.Sensor
{
    class MongoReplicaSensor : ICompositeSensor
    {
        private List<ISensor> _sensors;
        private int _id;
        private string _description;
        private int _interval;
        private DateTime _lastRefreshTime;
        private ServiceStatus _status;

        public MongoReplicaSensor(int id)
        {
            _id = id;
            this._sensors = new List<ISensor>();
        }

        public void AddComponent(ISensor sensor)
        {
            this.AddComponent(sensor as MongoSensor);
        }

        public void AddComponent(MongoSensor sensor)
        {
            this._sensors.Add(sensor);
        }

        public int Id
        {
            get { return _id; }
        }

        public string Description
        {
            get
            {
                return _description;
            }
            set
            {
                _description = value;
            }
        }

        public int Interval
        {
            get
            {
                return _interval;
            }
            set
            {
                _interval = value;
            }
        }

        public ServiceStatus Status
        {
            get { return _status; }
        }

        public string LastError
        {
            get
            {
                StringBuilder str = new StringBuilder();
                foreach (var s in _sensors)
                {
                    if (s.Status != ServiceStatus.Alive)
                    {
                        str.Append(s.Description + ": " + s.LastError + '\n');
                    }
                }
                return str.ToString();
            }
        }

        public DateTime LastRefreshTime
        {
            get
            {
                return _lastRefreshTime;
            }
        }

        public ServiceStatus Ping()
        {
            _lastRefreshTime = DateTime.Now;

            Parallel.ForEach<ISensor>(_sensors, (s) =>
            {
                s.Ping();
            });

            int alive = _sensors.Count(s => s.Status == ServiceStatus.Alive);
            if (alive == _sensors.Count())
            {
                _status = ServiceStatus.Alive;
                return _status;
            }
            if (alive * 2 > _sensors.Count())
            {
                _status = ServiceStatus.Unstable;
                return _status;
            }
            else
            {
                _status = ServiceStatus.Dead;
                return _status;
            }
        }
    }
}
